package com.onetime.mall.trading.utils;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.onetime.mall.trading.entity.OrderEntity;
import lombok.Data;


import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @author Lenovo
 */
@Data
public class OrderTask implements Delayed {

    /**
     * 订单类
     */
    private OrderEntity orderEntity;

    /**
     * 创建时间（毫秒）
     */
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private long time;


    /**
     * 过期时间（单位为毫秒，这里表示 10分钟）
     */
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private long expireTime;


    /*DelayQueue是一个泛型队列，它接受的类型是继承Delayed的，需要重写getDelay和compareTo方法*/


    /**
     * 初始化
     *
     * @param orderEntity 订单类
     * @param expireTime  延期时间（秒）
     */
    public OrderTask(OrderEntity orderEntity, long expireTime) {
        this.orderEntity = orderEntity;
        this.time = System.currentTimeMillis() + 1000 * expireTime;
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return super.toString();
    }


    /**
     * 该方法主要是判断消息是否到期（是否可以被读取出来）的依据。
     * 当返回负数，说明消息已到期，此时消息就可以被读取出来了。
     *
     * @param unit
     * @return
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return time + expireTime - System.currentTimeMillis();
    }

    /**
     * 该方法主要在往DelayQueue里面加入数据会执行，
     * 根据此方法的返回值判断数据应该排在哪个位置先。排得越前，越被消费
     * 这里根据取消时间来比较，如果取消时间小的，就会优先被队列提取出来
     *
     * @param o
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        OrderTask order = (OrderTask) o;
        long timeDifference = this.time - order.time;
        return timeDifference <= 0 ? -1 : 1;
    }
}
